%% Legal blahblah
% Copyright 2008 Alex Rattner
% This file is part of Pursuit.
% 
% Pursuit is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
% 
% Foobar is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
% 
% You should have received a copy of the GNU General Public License
% along with Pursuit.  If not, see <http://www.gnu.org/licenses/>.
%%

function main()

%% Preliminary setup
ServerIP = '130.91.241.168';
ServerPort = 1337;
name = 'Gazelle'; role = 'chasee';
GameName = 'GAME!!!';
GameType = 'pursuitv0.0';

%% Initial connection
sock = msconnect(ServerIP, ServerPort);
if (sock == -1) %bad connection
    disp('Bad Connection, buddy');
    return;
end

%% Give name and get game list
mssendraw(sock,uint8( ['{' name '}'] ));
games = getResponse(sock);

if strcmp(games, '{}') %list is empty, so make a new game
    gamestring = [ '{' GameName ',' GameType ',' role '}'];
    mssendraw(sock,uint8(gamestring));
    disp('Started a game');
else %join first game
    gamedata = split(games);
    gamestring = ['{' gamedata{1} ',' gamedata{2} ',' role '}'];
    mssendraw(sock, uint8(gamestring));
    disp('Joined a game');
end

%% Run control code
while (1)
    %get raw state info from server
    dataString = getResponse(sock);

    %parse data into cell array
    dataCells = split(dataString);
    %check for game end conditions
    if strcmp(dataCells{1}, 'win') || strcmp(dataCells{1}, 'lose')
        break;
    end
    %put parsed data into structs
    [me, him] = Strings2State( dataCells );
    %get input from chaser struct
    [a, alpha] = Gazelle(me, him);
    %build up response string
    actionstring = ['{' num2str(a) ',' num2str(alpha) '}'];
    %send response string
    mssendraw(sock, uint8(actionstring));
end
disp(dataCells{1});


%% End Game
msclose(sock);

%% Get String
function szResponse = getResponse(sock)
szResponse = [];

while ( isempty(szResponse) || (szResponse(length(szResponse)) ~= '}') )
    [val, res] = msrecvraw(sock,1); %get next char
    if (res < 0) %failure
        szResponse = '{}';
        break;
    end
    cNew = sprintf('%c', val);
    %append to string
    szResponse = [szResponse cNew];
end

%% Split String
function substrings = split(szIn)
substrings = {};
l = length(szIn);

if ( szIn(1) ~= '{' || szIn(l) ~= '}') %Bad Format
    return;
else
    szIn = szIn(2:(l-1)); %Chop off ends
    l = l-2;
end

commas = find(szIn == ',');
ind = 1;

%Split string into cell array of strings
while (l>0)
    if isempty(commas) %At last element
        substrings{ind} = szIn(1:length(szIn));
        szIn = '';
    else
        substrings{ind} = szIn(1:(commas(1)-1));
        szIn = szIn(commas(1)+1:length(szIn));
        if(length(commas) == 1)
            commas = [];
        else
            commas = commas(2:length(commas));
            commas = commas - length(substrings{ind}) - 1;
        end
    end
    ind = ind+1;
    l = length(szIn);
end

%% Strings to Statedata
function [me, him] = Strings2State (StateStrings)
%Initialize Structs
me = struct('x', 0, 'y', 0, 'u', 0, 'v', 0, 'theta', 0, 'omega', 0,...
       'accelMax', 0.75, 'accelMin', -0.75, 'alphaMax', 1, 'alphaMin', -1, 'r', 1);
him = struct('x', 0, 'y', 0, 'u', 0, 'v', 0, 'theta', 0, 'omega', 0,...
       'accelMax', -1, 'accelMin', -1, 'alphaMax', 1, 'alphaMin', -1, 'r', 1);

%Fill me
me.x = str2double(StateStrings{1});
me.y = str2double(StateStrings{2});
me.theta = str2double(StateStrings{3});
me.u = str2double(StateStrings{4});
me.v = str2double(StateStrings{5});
me.omega = str2double(StateStrings{6});

%Fill him
him.x = str2double(StateStrings{7});
him.y = str2double(StateStrings{8});
him.theta = str2double(StateStrings{9});
him.u = str2double(StateStrings{10});
him.v = str2double(StateStrings{11});
him.omega = str2double(StateStrings{12});